<?php

namespace App\Library\MakeFile;

class BaseMakeFile
{
    protected $module; // 模块名 User、Menu...
    protected $class;  // 类名 Controller、Model..
    protected $clientName; // 端名 b、pos...
    protected $codePrefix;  // 模块的返回码前缀

    protected $modulePath; // 模块的path
    protected $classPath; // class的path
    protected $clientPath; // 端的path

    protected $stubText;  // stub文件的内容、会更新成需要的内容
    protected $namespace; // 文件的命名空间
    protected $fileName;  // 文件名

    public const CLIENT_ENUM = [
        'B'      => 'api',
        'Pos'    => 'pos',
        "Applet" => 'applet'
    ];

    public function __construct(string $module, string $class, int $codePrefix)
    {
        $this->module     = $module;
        $this->class      = $class;
        $this->codePrefix = $codePrefix;
        $this->clientName = '';

        $this->modulePath = app_path() . "/Kuafu/{$module}";
        $this->classPath  = $this->modulePath . "/" . $this->class;
        $this->clientPath = $this->classPath;
        $this->setNamespace("App\Kuafu\\{$module}\\{$class}");
        $this->setFileName($this->module . $this->class . ".php");
    }

    protected function mkModuleDir()
    {
        // 建模块目录
        if (!file_exists($this->modulePath)) {
            mkdir($this->modulePath);
        }

        return $this;
    }

    // 获取stub信息
    protected function getStub()
    {
        $stub           = app_path() . "/Library/MakeFile/Stubs/{$this->class}.stub";
        $this->stubText = file_get_contents($stub);
        return $this;
    }

    // 建Class目录
    protected function mkClassDir()
    {
        if (!file_exists($this->classPath)) {
            mkdir($this->classPath);
        }

        return $this;
    }

    // 建端目录
    protected function mkClientDir()
    {
        if (!$this->clientName) {
            return $this;
        }

        $this->clientPath = $this->classPath . "/" . $this->clientName;
        if (!file_exists($this->clientPath)) {
            mkdir($this->clientPath);
        }

        return $this;
    }

    // 替换namespace
    private function replaceNameSpace()
    {
        $this->stubText = str_replace("{{ namespace }}", $this->namespace, $this->stubText);
        return $this;
    }

    // 替换class
    private function replaceClass()
    {
        // 正常替换
        $this->stubText = str_replace("{{ module }}", $this->module, $this->stubText);

        // 全部大写
        $this->stubText = str_replace("{{ MODULE }}", strtoupper($this->module), $this->stubText);

        // 首字母小写
        $this->stubText = str_replace("{{ mODULE }}", lcfirst($this->module), $this->stubText);

        return $this;
    }

    // 替换code
    private function replaceCode()
    {
        $this->stubText = str_replace("{{ code }}", $this->codePrefix, $this->stubText);
        return $this;
    }

    // 替换client
    private function replaceClient()
    {
        $this->stubText = str_replace("{{ client }}", $this->clientName, $this->stubText);
        return $this;
    }

    // 替换全部
    protected function replaceTotal()
    {
        $this->replaceNameSpace();
        $this->replaceClass();
        $this->replaceCode();
        $this->replaceClient();

        return $this;
    }

    // 重新写入文件
    protected function putFile()
    {
        // 存在就不更新了
        $wholeFileName = $this->clientPath . '/' . $this->fileName;
        if (!file_exists($wholeFileName)) {
            file_put_contents($wholeFileName, $this->stubText);
        }

        return $this;
    }

    // 添加写入文件
    protected function incrFile()
    {
        $routerName = self::CLIENT_ENUM[$this->clientName] ?? 'api';

        file_put_contents(base_path() . "/routes/{$routerName}.php", $this->stubText, FILE_APPEND);
        return $this;
    }

    // 自定义namespace
    protected function setNamespace(string $namespace)
    {
        $this->namespace = $namespace;
        return $this;
    }

    // 自定义文件名
    protected function setFileName(string $fileName)
    {
        $this->fileName = $fileName;
        return $this;
    }

    // 设置端名
    public function setClientName(string $clientName)
    {
        if (!$clientName) {
            return $this;
        }

        $this->clientName = $clientName;

        // 更新命名空间
        $this->setNamespace("App\Kuafu\\{$this->module}\\{$this->class}\\{$this->clientName}");
        return $this;
    }

    // 跑 - 生成模块
    public function doModule()
    {
        $this->mkModuleDir()
             ->getStub()
             ->mkClassDir()
             ->replaceTotal()
             ->putFile();

        echo "Create {$this->fileName} Success!" . PHP_EOL;
    }

    // 跑 - 生成路由
    public function doRouter(string $clientName)
    {
        $this->getStub()->setClientName($clientName)->replaceTotal()->incrFile();

        echo "Update Router Success!" . PHP_EOL;
    }
}
